/**
 *
 */

var categoryEditor = {};

categoryEditor.buttonEnable = true;

categoryEditor.stringUtils = {
		checkCategoryIdString : function(val){
			return val.match(/[^0-9A-Za-z_-]+/) === null;
		},
		iterateAppend: function(target, appendStr, count){
			for(var i = 0; i< count; i++){
				target += appendStr;
			}
			return target;
		}
};
categoryEditor.hideLayer = function(){
	$(".layer").hide();
	categoryEditor.hideProcessing();
	buttonEnable = true;
};
categoryEditor.hideContextMenu = function(){
	$(".context_menu").hide();
};

categoryEditor.createUrl = function(resource, userid, categoryid){
	var s = "/" + resource;
	if(userid){
		s = s + "/" + userid　;
	}
	if(categoryid){
		s = s + "/" + categoryid;
	}else{
		s = s + "/";
	}
	return s;
}

categoryEditor.showProcessing = function(){
	$(".processing").css("visibility","");
}
categoryEditor.hideProcessing = function(){
	$(".processing").css("visibility","hidden");
}

categoryEditor.messageTimer;
categoryEditor.showMessage = function(msg, option){
	
	option = option || {};
	
	if(!option.time){
		option.time = 5 * 1000;
	}
	
	if(!option.fadeoutTime){
		option.fadeoutTime = 3 * 1000;
	}
	if(!option.fadeinTime){
		option.fadeinTime = 3 * 1000;
	}
	if(!option.color){
		option.color = "white";
	}
	
	clearTimeout(categoryEditor.messageTimer);
	$("#message").hide();
	
	$("#message_str").css("color", option.color);
	$("#message_str").text(msg);
	$("#message").fadeIn(option.fadeinTime);
	categoryEditor.messageTimer = setTimeout(function(){
			$("#message").fadeOut(option.fadeoutTime);
		}, option.time);
};



categoryEditor.sidebarManager= function(spec){
	var that = {};	//public
	var my = {};		//private
	
	my.nonOpenAndClose = false;
	my.folderOpenStatusCookieName = "folder_open_ids";
	my.categoriesData = {};
	my.targetFolderIdx = -1;
		
	that.createContents = function(addEvent){
		my.getCategoriesDataByHttp();
		if(addEvent === true){
			my.addRelatedPartEventHandlers();
			my.addDialogEventHandlers();
		}
	};
	
	that.renameCategory = function(categoryid, name){
		categoryEditor.showProcessing();

		var category = my.getCategory(categoryid);
		category.name = name;
		my.putCategoriesDataByHttp(
				{
					successMessage: "カテゴリ名を変更しました。"
				});
		my.reflectDataIntoHtml();	
	};
	
	my.addEventHandlers = function(){
		
	    $('#sidebar').sortable({
			axis: "y", cursole: "move", opacity:0.5 , revert: false,
			cancel: "ul, li, .category_folder_add, .edit_category_folder",
			stop: function(){	
	    		my.nonOpenAndClose = true;
	    	},
	    	update :function(){
	    		if(spec.edditable){
		    		my.reflectFolderOrderToData();
		    		my.putCategoriesDataByHttp();
	    		}
	    	}
	    });
	    
		$(".categories").sortable({
			axis: "y", cursole: "move", opacity:0.5 , revert: false,
			update :function(event){
				if(spec.edditable){
					my.reflectCategoryOrderToData($(event.target));
					my.putCategoriesDataByHttp();
				}
				
			},
			cancel: ".create_new_category, .edit_category_folder"
		});
				
		$(".switch_edit_category_folder").click(function(event){
			my.switchEditCategoryFolderPanel(
					$(event.target).next(".edit_category_folder")
				);
		});
		
		$(".edit_category_folder").click(function(){
			my.nonOpenAndClose = true;
		});

		$(".category_folder").click(function(){
	    	if(my.nonOpenAndClose){
	    		my.nonOpenAndClose = false;
	    		return;
	    	}
	    	my.openAndCloseFolder(this);
		});
			
		//Category Folder Add Button
		$(".category_folder_add").click(function(){
			$("#glayLayer").show();
			
			$("#categoryFolderAddLayer").show();
			$("#categoryFolderAddText")
				.val("")
				.focus();
		});
		
		//Category Add Button
		$(".create_new_category").click(function(e){
			my.getTargetFolderIndex(e.target);
			
			$("#categoryAddErrorMsg").text("");
			$("#categoryIdText").val("")
			$("#categoryNameText").val("");
			
			$("#glayLayer").show();
			$("#categoryAddLayer").show();
			
			$("#categoryIdText").focus();
			
		});
		
		$("#glayLayer").click(function(){
			categoryEditor.hideLayer();
		});
		
		//Context Menu : Rename Folder -> show dialog
		$(".category_folder_rename").click(function(e){
			$("#glayLayer").show();
			$(".edit_category_folder").hide();
			
			my.getTargetFolderIndex(e.target);
			var name = my.categoriesData.folders[my.targetFolderIdx].id;
			
			$("#categoryFolderRenameLayer").show();
			$("#categoryFolderRenameText")
				.val(name)
				.focus()
				.select();
		});

		//Context Menu : Delete Folder -> show dialog
		$(".category_folder_delete").click(function(e){
			
			my.getTargetFolderIndex(e.target);
						
			$("#glayLayer").show();
			$(".edit_category_folder").hide();
			$("#categoryFolderDeleteLayer").show();
			$("#btnCancelDeleteCategoryFolder").focus();
		});
	};	
	
	my.addRelatedPartEventHandlers = function(){
		//コンテキストメニュー非表示処理(別の箇所をクリックした場合)
		$(document).mousedown( function (e) {
			if($(e.target).hasClass("context_menu_option")){
				return;
			}
			$(".context_menu").hide();
		});		
	};
	
	my.addDialogEventHandlers = function(){
		
		//Dialog : Rename Category Folder : Button
		$("#btnRenameCategoryFolder").click(function(){
			my.renameCategoryFolder();
		});
		//Dialog : Rename Category Folder  :Enter Key
		$("#categoryFolderRenameText, #btnRenameCategoryFolder").bind("keydown", function(event){
			var key = event.keyCode || event.which;
			if(key === 13){
				my.renameCategoryFolder();
			}
		});
		
		//Dialog : Delete Category Folder : Button
		$("#btnDeleteCategoryFolder").click(function(e){
			my.deleteCategoryFolder();
		});

		//Dialog : Delete Category Folder : Cancel Button
		$("#btnCancelDeleteCategoryFolder").click(function(){
			categoryEditor.hideLayer();
		});
		
		//Dialog : Add Category Folder : Add Button
		$("#btnAddCategoryFolder").click(function(){
			my.addCategoryFolder();
		});
		//Dialog : Add Category Folder : Enter Key
		$("#categoryFolderAddText, #btnAddCategoryFolder").bind("keydown", function(event){
			var key = event.keyCode || event.which;
			if(key === 13){
				my.addCategoryFolder();
			}
		});
		
		
		//Dialog : Add Category : Add Button
		$("#btnAddCategory").click(function(){
			my.addCategory();
		});
		
		//Dialog : Add Category : Enter Key
		$("#categoryIdText,#categoryNameText, #btnAddCategory").bind("keydown", function(event){
			var key = event.keyCode || event.which;
			if(key === 13){
				my.addCategory();
			}
			
		});
		
	};	
	
	
	my.getCategoriesDataByHttp = function(){
		
		$.ajax({
			type : "GET",
			url : categoryEditor.createUrl("categories", spec.userid),
			async : false,
			dataType : "json",
			
			success : function(jsonResponse){
				my.categoriesData = jsonResponse;
				my.reflectDataIntoHtml();
			},
			
			error : function(){
				categoryEditor.showMessage("カテゴリの取得に失敗しました。　：通信エラー", { color : "red"});
			}
			
		});
	};
		
	my.putCategoriesDataByHttp = function( option){
				
		option = option || {};
		var async = true;
		option.async =  option.async !== false;	
				
		$.ajax({
			type : "PUT",
			url : categoryEditor.createUrl("categories", spec.userid),
			async : option.async,
			contentType : "application/json; charset=utf-8",
			data : JSON.stringify(my.categoriesData),
			dataType : "json",
			success : function(){
				if(option.successMessage){
					categoryEditor.showMessage(option.successMessage);
				}
			},
			error : function(xhr, error){
				var errMsg;
				if(option.errorMessage){
					errMsg = option.errorMessage;
				}else{
					errMsg = "カテゴリの更新に失敗しました。　：通信エラー";
				}
				categoryEditor.showMessage(errMsg , { color : "red"});
			}
		});
	};

	my.reflectDataIntoHtml = function(){
		
		var folderOpenIds =  [];
		var folderAllOpen = false;
		
		var cookieVal = $.cookie(my.folderOpenStatusCookieName);
		if(spec.edditable && (cookieVal || cookieVal === "")){
			folderOpenIds = $.cookie(my.folderOpenStatusCookieName).split(",");
		}else{
			folderAllOpen = true;
		}
		
		
		$("#sidebar").text("");
		$("#sidebar").children().remove();
		
		$.each(my.categoriesData.folders, function(){
			var dt = $("<dt>").addClass("category_folder").addClass("corner_rounded_low");
			dt.attr("title", this.id);
			var title = $("<div>")
				.addClass("category_folder_name")
			title.text(this.id);
			//title.attr("title", this.id);
			dt.append(title);
			
			if(spec.edditable){
				dt.append(
						$("<div>").addClass("switch_edit_category_folder").text("▼")	
					);
				var div = $("<div>")
					.addClass("edit_category_folder")
					.addClass("corner_rounded_medium")
					.addClass("context_menu")
					.css({"display" : "none"});
				var li1 = $("<li>");
				li1.append(
						$("<span>")
							.addClass("category_folder_rename")
							.addClass("context_menu_option")
							.append("名前の変更")
					);
				var li2 = $("<li>");
				li2.append(
						$("<span>")
							.addClass("category_folder_delete")
							.addClass("context_menu_option")
							.append("削除")
					);
				var ul = $("<ul>");
				ul.append(li1).append(li2);
				div.append(ul);
				dt.append(div);
			}

			
			var dd = $("<dd>").addClass("categories_dd");
			
			var ul = $("<ul>").addClass("categories");
			
			var selectedCategoryExist = false;
			
			for(var i = 0; i < this.categories.length; i++){
				var url = categoryEditor.createUrl("users", spec.userid, this.categories[i].id);
				var li = $("<li>").addClass("corner_rounded_low");

				if(spec.categoryid && spec.categoryid === this.categories[i].id){
					li.addClass("category_selected");
					var div = $("<div>").text(this.categories[i].name);
					div.addClass("category_name");
					li.append(div);
					var a = $("<a>").attr("href", url);
					li.append(a);
					selectedCategoryExist = true;
				}else{
					li.addClass("category");
					
					var a = $("<a>").attr("href", url);
					var div = $("<div>").text(this.categories[i].name);
					div.addClass("category_name");
					a.append(div);
					li.append(a);
				}
				
				if(this.categories[i].accessible){
					li.addClass("accessible");
				}
				
				li.attr("title", this.categories[i].name);

				ul.append(li);
			}
			
			if(spec.edditable){
				ul.append(
						$("<li>").addClass("create_new_category").addClass("corner_rounded_low")
							.append("＋")
						);
			}
			
			dd.append(ul);
			if(!folderAllOpen &&  $.inArray(this.id, folderOpenIds) === -1){
				if(!selectedCategoryExist){
					dd.css("display", "none");
				}
				
			}
			
			var div2 = $("<div>").addClass("category_folder_set");
			div2.append(dt).append(dd);

			$("#sidebar").append(div2);
		});

		if(spec.edditable){
			var div3 = $("<div>")
				.addClass("category_folder_add")
				.addClass("corner_rounded_low");
			div3.text("＋");
			$("#sidebar").append(div3);
		}

		my.addEventHandlers();
	};	
	
	if(spec.edditable){
		my.saveFolderOpenStatusInCookie = function(optOpenCategoryId){
			var cookieName = my.folderOpenStatusCookieName;
			
			//Clear
			$.cookie(cookieName, '', { expires: -1 });
			
			var openFolderIds = [];
			$(".categories_dd").each(function(i){
				if($(this).css("display") !== "none"){
					openFolderIds.push(
							my.categoriesData.folders[i].id
						);
				}
			});
			if(optOpenCategoryId){
				openFolderIds.push(optOpenCategoryId);
			}
						
			$.cookie(cookieName, openFolderIds.toString(), { expires: 365 });		
		};
	}else{
		my.saveFolderOpenStatusInCookie = function(){};
	}
	

	
	my.addCategoryFolder = function(){
		
		var name = $("#categoryFolderAddText").val();

		if($.trim(name) === ""){
			return;
		}
		
		categoryEditor.showProcessing();
		
		my.categoriesData.folders.push(
					{	
						id : name,
						categories : []
					}
				);
		my.saveFolderOpenStatusInCookie(name);
		my.reflectDataIntoHtml();
		my.reflectFolderOrderToData();
		my.putCategoriesDataByHttp(
				{ successMessage : "フォルダを追加しました。",
					errorMessage : "フォルダの追加に失敗しました。 : 通信エラー"}
			);
		categoryEditor.hideLayer();
	};	
	
	my.addCategory = function(){
		var idVal = $("#categoryIdText").val().trim();
		var nameVal = $("#categoryNameText").val().trim();
		if(idVal.trim() === "" || nameVal.trim() === ""){
			return;
		}
		if(!categoryEditor.stringUtils.checkCategoryIdString(idVal)){
			$("#categoryAddErrorMsg").text("カテゴリIDは半角英数字、-/のみ可能です。");
			return;
		}
				
		//ID 存在チェック
		if(my.checkCategoryIdIsAlreadyExists(idVal)){
			$("#categoryAddErrorMsg").text("同じカテゴリIDが既に存在します。");
			return;
		}
		
		if(categoryEditor.buttonEnable){
			categoryEditor.buttonEnable = false;
		}else{
			return;
		}
		
		var targetFolder = my.categoriesData.folders[my.targetFolderIdx];
		
		targetFolder.categories.push(
				{
					id : idVal,
					name : nameVal,
					order : targetFolder.categories.length,
					content : JSON.stringify([{"data": nameVal}])
				}
			);
		
		categoryEditor.showProcessing();
		
		my.putCategoriesDataByHttp({ async : false});
		
		location = categoryEditor.createUrl("users", spec.userid, idVal);
	};

	my.deleteCategoryFolder = function(){
		
		categoryEditor.showProcessing();
		
		var currentCategoryIsChild = false;
		if(spec.categoryid){
			var childCategories = my.categoriesData.folders[my.targetFolderIdx].categories;
			$.each(childCategories, function(){
				if(spec.categoryid === this.id){
					currentCategoryIsChild =true;
					return;
				}
			});
		}
		 
		my.categoriesData.folders.splice(my.targetFolderIdx, 1);
		my.reflectDataIntoHtml();
		my.putCategoriesDataByHttp({successMessage : "フォルダを削除しました。"});
		my.saveFolderOpenStatusInCookie();
		categoryEditor.hideLayer();
		
		if(spec.categoryManager){
			spec.categoryManager.hideTreeWrapper();
		}

	};
	
	
	my.switchEditCategoryFolderPanel = function(divEditCategoryFolder){
		my.nonOpenAndClose = true;		
		if(divEditCategoryFolder.css("display") === "none"){
			divEditCategoryFolder.css("display", "block"); 
		}else{
			divEditCategoryFolder.css("display", "none");
		}
	};
	
	my.openAndCloseFolder = function(target){
    	$(target).closest('div').children('dd').each(function(i, v){
    		if($(v).css("display") === "none"){
        		$(v).css("display", "block");
    		}else{
        		$(v).css("display", "none");
    		}
    	});
    	my.saveFolderOpenStatusInCookie();
	};	
	
	my.getTargetFolderIndex = function(element){
		var d = $(element).closest("div[class=category_folder_set]");
		my.targetFolderIdx =  $("#sidebar div[class=category_folder_set]").index(d);
	};
	
	my.renameCategoryFolder = function(){
		var val = $("#categoryFolderRenameText").val();
		if(val.trim() === ""){
			return;
		}
		if(my.categoriesData.folders[my.targetFolderIdx].id  === val){
			categoryEditor.hideLayer();
			return;
		}
		
		categoryEditor.showProcessing();
		
		my.categoriesData.folders[my.targetFolderIdx].id = val;
		my.saveFolderOpenStatusInCookie();
		my.reflectDataIntoHtml();
		categoryEditor.hideLayer();
		
		my.putCategoriesDataByHttp({ successMessage : "フォルダ名を変更しました。" });
	};	
	
	my.reflectFolderOrderToData = function(){
		
		$("#sidebar").find(".category_folder_name").each(function(idx){
			var folderId = $(this).text();
			var folder = my.getFolder(folderId);
			folder.order = idx;
		});
		my.sortCategoriesDataByOrderField();
	};
	
	my.reflectCategoryOrderToData = function(target){
		
		target.find("li a").each(function(idx){
			var strs = $(this).attr("href").split("/");
			var categoryId = strs[strs.length - 1];
			var category = my.getCategory(categoryId);
			category.order = idx;
		});

	};
	
	my.sortCategoriesDataByOrderField = function(){
		var newFolders = [];
		for(var i = 0; i < my.categoriesData.folders.length; i++){
			$.each(my.categoriesData.folders, function(){
				if(this.order === i){
					newFolders.push(this);
					return;
				}
			});
		}

		my.categoriesData.folders = newFolders;
	};
	
	my.getFolder = function(id){
		var that;
		$.each(my.categoriesData.folders, function(){
			if(this.id === id){
				that = this;
				return;
			}
		});
		return that;
	};
	
	my.getCategory = function(id){
		var that;
		$.each(my.categoriesData.folders, function(){
			for(var i=0;  i < this.categories.length; i++){
				if(this.categories[i].id === id){
					that = this.categories[i];
					break;
				}
			}
		});
		return that;
	}
	
	my.getCategoryIdList = function(){
		var categoryIds = [];
		$.each(my.categoriesData.folders, function(){
			$.each(this.categories , function(){
				categoryIds.push(this.id);
			});
		});
		return categoryIds;
	}	
	
	my.checkCategoryIdIsAlreadyExists = function(categoryId){
		categoryIds = my.getCategoryIdList();
		return $.inArray(categoryId, categoryIds) !== -1;
	};	

	return that;

};

categoryEditor.categoryManager = function(spec, sidebarManager){
	var that = {};	//public
	var my = {};		//private
	
	my.clip;
	my.clipboardText = "";
	
	that.createContent = function(){
		my.addEventHandlers();
		if(spec.categoryid){
			my.createTree();
			my.addTreeEventHandlers();
			my.addClipboardEventHandlers();
		}
	};
	
	that.hideTreeWrapper = function(){
		$("#tree_wrapper").hide();
	};
	
	that.resizeArea = function(type){
		var maxTop = my.getMostBottomPartPosition() + 50;
		var maxLeft = my.getMostRightPartPosition();
		if(maxLeft < 700){
			maxLeft = 700;
		}
		
		var isOpenEvent = ( type === 'open_node' );

		if($("#tree").height() < maxTop  || !isOpenEvent){
			$("#tree").height(maxTop);
			$("#tree_wrapper").height(maxTop);
		}

		
		if($("#tree").width() < maxLeft || !isOpenEvent){
			$("#tree").width(maxLeft);
			$("#tree_wrapper").width(maxLeft);
		}
		$("#tree_wrapper").resizable({ minWidth : maxLeft , minHeight : maxTop});

	};	
	
	

	my.putCategoryDataByHttp = function(categoryData, option){

		option = option || {};
		
		$.ajax({
			type : "PUT",
			url : categoryEditor.createUrl("categories", spec.userid, spec.categoryid),
			async : true,
			contentType : "application/json; charset=utf-8",
			data :  JSON.stringify(categoryData),
			dataType : "json",
			success : function(){
				if(option.successMessage){
					categoryEditor.showMessage(option.successMessage);
				}
			},
			error : function(xhr){
				var msg;
				if(xhr.statusText.indexOf("EntityPropertySizeLimitException") !== -1){
					msg = "カテゴリの更新に失敗しました。　： 制限サイズオーバーです。";
				}else{
					msg = "カテゴリの更新に失敗しました。　：通信エラー";
				}
				categoryEditor.showMessage(msg , { color : "red"});
			}
		});
	};
	
	my.putAccessibleInfoByHttp = function(accessible){
				
		$.ajax({		
			type : "PUT",
			url : categoryEditor.createUrl("categories", spec.userid, spec.categoryid),
			async : false,
			data : {
				accessible : accessible
			},
			success : function(){
				categoryEditor.showMessage("公開設定を変更しました。 ");
				spec.accessible = $("input[name=accessible]:checked").val() === "true";
				if(spec.accessible){
					
					$("#label_accessible_no").hide();
					$("#label_accessible_yes").show();
				}else{
					$("#label_accessible_yes").hide();
					$("#label_accessible_no").show();
				}
			},
			error : function(){
				categoryEditor.showMessage("公開設定の更新に失敗しました。　：通信エラー", { color : "red"});
			}
		});
	};
	
	my.getJsonCategoryDataByHttp = function(){
		$.ajax({
			url : categoryEditor.createUrl("categories", spec.userid, spec.categoryid),
			type : "GET",
			async : false,
			contentType : "application/json; charset=utf-8"
		});
	};	
	
	
	 my.deleteCategoryByHttp= function(){
		$.ajax({
			type : "DELETE",
			url : categoryEditor.createUrl("categories", spec.userid, spec.categoryid),
			async : false,
			success : function(){
					categoryEditor.showMessage("カテゴリを削除しました。");
					categoryEditor.hideLayer();
					that.hideTreeWrapper();
					sidebarManager.createContents();
					
			},
			error :function(){
				categoryEditor.showMessage("カテゴリの削除に失敗しました。　：通信エラー", { color : "red"});
			}
		});
	};

	my.addEventHandlers = function(){

		$("#message_close").click(function(){
			$("#message").hide();
		});
		
		if(spec.edditable){
	
			$("#menu_switch_category_edit").click(function(){
				$("#menu_edit_category").show();
			});
			
			$("#menu_switch_category_data").click(function(){
				$("#menu_edit_data").show();
			});
			
			$("#category_rename").click(function(){
				$("#glayLayer").show();
				$("#menu_edit_category").hide();
				
				$("#categoryRenameLayer").show();
				$("#renameCategoryText").val(spec.categoryName);
				$("#renameCategoryText").focus();
				$("#renameCategoryText").select();	
			});
			
			$("#btnRenameCategory").click(function(){
				my.renameCategory();
			});
			
			//Enterでの確定
			$("#renameCategoryText").bind("keydown", function(event){
				var key = event.keyCode || event.which;
				if(key === 13){
					my.renameCategory();
				}
			});
			
			$("#category_delete").click(function(){
				$("#glayLayer").show();
				$("#menu_edit_category").hide();
				
				var categoryName = $("#category_title").text();
				
				$("#categoryDeleteLayer").show();
				$("#btnCancelDeleteCategory").focus();
			});
			
			$("#btnDeleteCategory").click(function(){
				my.deleteCategory();
			});
			
			$("#btnDeleteCategory").bind("keydown", function(event){
				var key = event.keyCode || event.which;
				if(key === 13){
					my.deleteCategoryByHttp();
				}
			});
	
			$("#btnCancelDeleteCategory").click(function(){
				categoryEditor.hideLayer();
			});
			
			$("#btnCancelDeleteCategory").bind("keydown", function(event){
				var key = event.keyCode || event.which;
				if(key === 13){
					categoryEditor.hideLayer();
				}
			});
			
			
			$("#publish_config").click(function(){
				$("#glayLayer").show();
				$("#menu_edit_category").hide();
				
				$("input[name=accessible]").val([spec.accessible.toString()]);
				$("#publish_config_layer").show();
			});
			
			$("#btn_publish_config").click(function(){
				my.changePublishConfig();
				categoryEditor.hideLayer();
			});
			$("#btnCancelDeleteCategory").bind("keydown", function(event){
				var key = event.keyCode || event.which;
				if(key === 13){
					my.changePublishConfig();
					categoryEditor.hideLayer();
				}
			});
			
			$("#save_current_state").click(my.saveCurrentState);
			
			
			$("#export_json").click(function(){
				$("#menu_edit_data").hide();

				location = categoryEditor.createUrl(
						"categories", spec.userid, spec.categoryid)
						+ "?jsonFileDownload=true";

			});
			
			$("#import_json").click(function(){
				$("#glayLayer").show();
				$("#menu_edit_data").hide();
				$("#json_upload_layer").show();
			});
			
			$("#jsonfile").change(function(){
				var v = $("#jsonfile").val();
				if(!v.match(/\.(json)$/i)){
					alert("該当の拡張子のファイルは選択できません。");
					$("#jsonfile").val("");
					return false;
				}
			});
			
//			$("#btnJsonUpload").click(function(){
//				$("#jsonUploadForm").submit();
//			});
			
			
			$("#tree_wrapper").resizable({
				stop: function(e ,ui){
					var width = $("#tree_wrapper").css("width");
					var height = $("#tree_wrapper").css("height");
					$("#tree").width(width);
					$("#tree").height(height);
					
					var maxX = my.getMostRightPartPosition();
					if(maxX < 700){
						maxX = 700;
					}
					var maxY = my.getMostBottomPartPosition();
					$("#tree_wrapper").resizable({ minWidth : maxX , minHeight : maxY});
					
				}
			});
			
		}
		

	};
	
	my.addClipboardEventHandlers = function(){
		ZeroClipboard.setMoviePath( '/js/lib/zeroclipboard/ZeroClipboard.swf' );
		my.clip = new ZeroClipboard.Client();
		my.clip.setHandCursor( true );
		my.clip.flashLoaded = false;
		
		my.clip.addEventListener('load', function (client) {
			my.clip.flashLoaded = true;
			$("#copy_to_clipboard").css("visibility","");
		});

		my.clip.addEventListener('mouseDown', function (client) {
			my.clip.setText($("#tree").jstree('getTextFormatData'));
		});

		my.clip.addEventListener('complete', function (client, text) {
			var msg = "クリップボードにデータをコピーしました。";
			if($("#tree").jstree('get_selected').length !== 0){
				msg += " [選択された配下] ";
			}
			categoryEditor.showMessage(msg,
					{time : 2000, fadeinTime : 1000, fadeoutTime: 1000});
		});
		
		my.clip.glue("copy_to_clipboard");
		
	};

	my.addTreeEventHandlers = function(){
		
		$("#tree").bind(
				"loaded.jstree open_node.jstree close_node.jstree "
					+"create.jstree remove.jstree paste.jstree", 
				function (e) {
//					console.debug("event : need resize : " +  e.handleObj.type);
					that.resizeArea(e.handleObj.type);
				}
		);
		
		if(spec.edditable){
			$("#tree").bind(
				"rename.jstree create.jstree remove.jstree paste.jstree",
				// paste.jstree? error
				function(e, data){
//					console.debug("event modified data : " + e.handleObj.type);
					
//					my.putCategoryDataByHttp(data.inst.get_json($("#tree")));
					my.putCategoryDataByHttp($("#tree").jstree('get_json', -1, []));
					
				}
				
			);
		};
	};

	my.deleteCategory = function(){
		categoryEditor.showProcessing();
		my.deleteCategoryByHttp();
	};
	
	my.renameCategory = function(){
		var val = $("#renameCategoryText").val();
		if( val === ""){
			return;
		}
		
		if(spec.categoryName === val){
			categoryEditor.hideLayer();
			return;
		}
		
		spec.categoryName = val;
		sidebarManager.renameCategory(spec.categoryid, spec.categoryName);
		$("#category_title").text(val).attr("title", val);
		categoryEditor.hideLayer();
		
	};
	
	my.changePublishConfig = function(){
		
		var val = $("input[name=accessible]:checked").val() === "true";
		if(spec.accessible === val){
			categoryEditor.hideLayer();
			return;
		}
		
		categoryEditor.showProcessing();
				
		my.putAccessibleInfoByHttp(val);
	};
	
	my.saveCurrentState = function(){
		my.putCategoryDataByHttp(
				$("#tree").jstree('get_json', -1, []),
				{ successMessage : "現在の状態を保存しました。" });
		categoryEditor.hideContextMenu();
	};
	
	my.getMostBottomPartPosition = function(){
		var max = 0;
		$.each(
			$("#tree a"),
			function(idx, element){
				var top = element.offsetTop +element.offsetHeight + 10;
				if(top > max){
					max = top;
				}
			}
		);
		return max;	
	};
	
	my.getMostRightPartPosition = function(){
		var max = 0;
		$.each(
			$("#tree a"),
			function(idx, element){
				var left =  element.offsetLeft + element.offsetWidth + 10;
				if(left > max){
					max = left;
				}
			}
		);
		return max;
	};
	

	my.createTree = function(){
		
		my.jstreeObj = $("#tree").jstree({ 
			"core" : {"animation" : 0},
			
			"plugins" : ["json_data", "themes", "ui", "crrm", "hotkeys", 
			              //"cookies",
							"dnd", "contextmenu", "unique"],
							
			"json_data" : {
				"ajax" : { 
					"url" : categoryEditor.createUrl("categories", spec.userid, spec.categoryid),
				}
				,"progressive_render" : false
			},
			
			"themes" : {
				"theme" : "mytheme",
				"dots" : true,
				"icons" : false
			},
			
			"ui" : {
				"select_limit" : 2,
				"select_multiple_modifier" : "alt",
				"selected_parent_close" : "select_parent",
				"initially_select" : [ "phtml_2" ]
			},
			
			"crrm" : { 
				"move" : {
					"check_move" : function (m) {
						if($(m.r[0]).parent().parent().attr("id") === "tree"){
							return false;
						}
						return true;
					}
				}
			},
			"dnd" : {
				"drop_target" : false,
				"drag_target" : false
			},
			"contextmenu" : createContextmenuConfig(),
			"hotkeys" : createHotkeyConfig()
		});
		
		function createHotkeyConfig(){
			var hotkey = {};
			if(spec.edditable){
				hotkey.n = function(){
					var o = this.data.ui.hovered || this.data.ui.last_selected;
					this.create(o, "last" , null, null, false);
					this.deselect_all();
					this.select_node(o);
					return false;
				};
				hotkey.del = function(){
					this.remove(this.data.ui.hovered || this._get_node(null)); 
				};

				hotkey["e"] = function(){
					this.rename(
							this.data.ui.hovered || this.data.ui.last_selected 
						);
				};
				
				hotkey.c = function(){
					var o = this.data.ui.hovered || this.data.ui.last_selected;
					this.copy(o);
				};
				hotkey.x = function(){
					var o = this.data.ui.hovered || this.data.ui.last_selected;
					this.cut(o);
				};
				hotkey.v= function(){
					var o = this.data.ui.hovered || this.data.ui.last_selected;
					this.paste(o);
				};

			}else{
				hotkey.del = function(){};
			}
			
			hotkey["shift+right"] = function(){
				var o = this.data.ui.hovered || this.data.ui.last_selected;
				this.open_all(o);
			};
			hotkey["shift+left"] = function(){
				var o = this.data.ui.hovered || this.data.ui.last_selected;
				this.close_all(o);
			};
			
			return hotkey;
		}
		
		function createContextmenuConfig(){
			var contextmenu = {};
			contextmenu.select_node = true;
			contextmenu.show_at_node = false;
			contextmenu.items = {};
			if(spec.edditable){
				contextmenu.items.rename = {
					"separator_before"	: false,
					"separator_after"	: true,
					"label"				: categoryEditor.stringUtils.iterateAppend("編集", "&nbsp;" , 11)+"(e)",
					"action"			: 
						function (obj) { 
							this.rename(obj); 
						 }
				};
				contextmenu.items.create = {
					"separator_before"	: true,
					"label"				: categoryEditor.stringUtils.iterateAppend("作成", "&nbsp;" , 11)+"(n)",
					"action"			: 
						function (obj) { 
							this.create(obj, "last" , null, null, false);
						}
				};
				contextmenu.items.remove = {
					"separator_after"	: true,
					"icon"				: false,
					"label"				: categoryEditor.stringUtils.iterateAppend("削除", "&nbsp;" , 11)+"(Delete)",
					"action"			: 
						function (obj) { 
							this.remove(obj);
						}
				};
				contextmenu.items.cut = {
					"label" : categoryEditor.stringUtils.iterateAppend("切り取り", "&nbsp;" , 5)+"(x)",
					"action" : function(obj){this.cut(obj)}
				};
				contextmenu.items.copy = {
					"label" : categoryEditor.stringUtils.iterateAppend("コピー", "&nbsp;" , 8)+"(c)",
					"action" : function(obj){this.copy(obj)}
				};
				contextmenu.items.paste = {
					"label" : categoryEditor.stringUtils.iterateAppend("貼り付け", "&nbsp;" , 5)+"(v)",
					"action" : function(obj){
						this.paste(obj);
					}
				};
//				contextmenu.items.copyToClipboard = {
//						"label" : categoryEditor.stringUtils.iterateAppend("クリップボードにコピー", "&nbsp;" , 3)+"(c)",
//						"action" : function(obj){
//							
//						},
//						"separator_after"	: true,
//				};
				
			}
			contextmenu.items.open_all = {
				"label" : categoryEditor.stringUtils.iterateAppend("全て開く", "&nbsp;" , 5)+"(Shift + →)",
				"action" : function(obj){
					this.open_all(obj);
				}
			};
			contextmenu.items.close_all = {
					"label" : categoryEditor.stringUtils.iterateAppend("全て閉じる", "&nbsp;" , 2)+"(Shift + ←)",
					"action" : function(obj){
						this.close_all(obj);
					}
			};
			return contextmenu;
		}
		
	};

	
	return that;
}

